// index.js
const express = require('express');
const cors = require('cors');
const multer = require('multer');
const path = require('path');
const fs = require('fs');

const app = express();
const PORT = Number(process.env.PORT || 9990);
const HOST = process.env.HOST || '0.0.0.0';
const uploadsDir = path.join(__dirname, 'uploads');
const PUBLIC_BASE_URL = process.env.PUBLIC_BASE_URL || `http://10.50.80.54:${PORT}`;
const uploadEndpoint = `${PUBLIC_BASE_URL}/upload`;
// 内存中存储最近接收到的非文件数据（最多保留 50 条）
const recentPosts = [];

// 允许 RN 调试器或浏览器跨域
app.use(cors());
app.use(express.urlencoded({ extended: true }));
// 解析 JSON body（支持非文件的其它数据）
app.use(express.json());

// Serve uploaded assets so other devices can preview them.
app.use('/uploads', express.static(uploadsDir));

// 保存到当前目录下的 uploads 文件夹
fs.mkdirSync(uploadsDir, { recursive: true });

const sanitize = value => value.replace(/[^a-z0-9_-]/gi, '_');
const storage = multer.diskStorage({
  destination: (_req, _file, cb) => cb(null, uploadsDir),
  filename: (_req, file, cb) => {
    const ext = path.extname(file.originalname).toLowerCase();
    const base = sanitize(path.basename(file.originalname, ext) || 'file');
    const unique = `${Date.now()}-${Math.floor(Math.random() * 1e6)}`;
    cb(null, `${unique}-${base}${ext}`);
  }
});
const upload = multer({ storage });

// 为/upload路径添加GET请求处理，显示简单的上传表单
app.get('/upload', (req, res) => {
  res.send(`
    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="UTF-8">
        <title>文件上传</title>
    </head>
    <body>
        <h2>文件上传服务</h2>
        <p>此服务仅支持通过API上传文件。</p>
        <p>请使用POST方法向以下端点发送文件：</p>
        <code>${uploadEndpoint}</code>
        <p>服务运行在: ${PUBLIC_BASE_URL}</p>
    </body>
    </html>
  `);
});

// 单文件/多文件都兼容
app.post('/upload', upload.any(), (req, res) => {
  const rawFiles = req.files || [];
  const files = rawFiles.map(file => ({
    field: file.fieldname,
    originalName: file.originalname,
    filename: file.filename,
    size: file.size,
    mimetype: file.mimetype,
    urls: [`${PUBLIC_BASE_URL}/uploads/${file.filename}`]
  }));

  const message = rawFiles.length
    ? `已成功接收 ${rawFiles.length} 个文件。`
    : '未收到文件 (仅收到字段或空)。';

  // 记录接收到的非文件字段（req.body）和文件元数据到 recentPosts
  const postEntry = {
    id: Date.now() + '-' + Math.floor(Math.random() * 1e6),
    timestamp: new Date().toISOString(),
    fields: req.body || {},
    files,
    message
  };
  recentPosts.unshift(postEntry);
  // 保持数组长度限定
  if (recentPosts.length > 50) recentPosts.length = 50;

  console.log('renwei - 收到字段', req.body);
  console.log('renwei - 收到文件', files);
  console.log('renwei - ' + message);

  res.json({
    status: 'ok',
    uploadCount: files.length,
    message,
    files,
    uploadEndpoint,
    entry: postEntry
  });
});

app.get('/', (_req, res) => {
  console.log('renwei - 服务根路径被访问');
  // 动态页面，前端会调用 /api/list 获取文件与其它接收的数据并展示
  res.send(`
    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="UTF-8">
        <title>文件上传服务 - 已接收内容</title>
        <style>
            body { font-family: Arial, sans-serif; margin: 20px; background-color: #f5f5f5; }
            .container { max-width: 1000px; margin: 0 auto; background-color: white; padding: 20px; border-radius: 8px; box-shadow: 0 0 12px rgba(0,0,0,0.08); }
            h1 { text-align: center; }
            .grid { display: grid; grid-template-columns: 1fr; gap: 16px; }
            .box { padding: 12px; border: 1px solid #eee; border-radius: 6px; background: #fff; }
            .file-list { display:flex; flex-wrap:wrap; gap:12px; }
            .file-item { width: 160px; border:1px solid #f0f0f0; padding:8px; border-radius:6px; text-align:center; background:#fafafa }
            .file-item img { max-width:100%; max-height:90px; display:block; margin:0 auto 8px }
            .meta { font-size: 12px; color: #555 }
            pre { background:#f8f8f8; padding:10px; border-radius:4px; overflow:auto }
            a { color:#007bff }
        </style>
    </head>
    <body>
      <div class="container">
        <h1>已接收内容</h1>
        <div class="grid">
          <div class="box">
            <strong>服务信息:</strong>
            <div class="meta">服务地址: ${PUBLIC_BASE_URL} · 上传接口: ${uploadEndpoint}</div>
          </div>

          <div class="box" id="filesBox">
            <h3>已上传文件</h3>
            <div id="files" class="file-list">加载中…</div>
          </div>

          <div class="box" id="postsBox">
            <h3>最近接收的其它数据</h3>
            <div id="posts">加载中…</div>
          </div>

        </div>
      </div>

      <script>
        async function loadList() {
          try {
            const res = await fetch('/api/list');
            const data = await res.json();
            const filesEl = document.getElementById('files');
            const postsEl = document.getElementById('posts');
            filesEl.innerHTML = '';

            if (!data.files || data.files.length === 0) {
              filesEl.innerHTML = '<div class="meta">暂无文件</div>';
            } else {
              data.files.forEach(f => {
                const div = document.createElement('div');
                div.className = 'file-item';
                const lower = (f.filename || '').toLowerCase();
                const isImage = /\.(png|jpe?g|gif|webp|svg)$/i.test(lower);
                if (isImage) {
                  const img = document.createElement('img');
                  img.src = f.url;
                  img.alt = f.filename;
                  div.appendChild(img);
                } else {
                  const icon = document.createElement('div');
                  icon.style.padding = '8px 0';
                  icon.textContent = '📄';
                  div.appendChild(icon);
                }
                const name = document.createElement('div');
                // 使用字符串拼接以避免与服务端模板冲突
                name.innerHTML = '<a href="' + f.url + '" target="_blank" rel="noopener">' + escapeHtml(f.filename) + '</a>';
                const meta = document.createElement('div');
                meta.className = 'meta';
                meta.textContent = (f.size != null ? (Math.round(f.size/1024)+' KB') : '') + (f.mtime ? (' · ' + new Date(f.mtime).toLocaleString()) : '');
                div.appendChild(name);
                div.appendChild(meta);
                filesEl.appendChild(div);
              });
            }

            if (!data.recentPosts || data.recentPosts.length === 0) {
              postsEl.innerHTML = '<div class="meta">暂无接收的其它数据</div>';
            } else {
              postsEl.innerHTML = '';
              data.recentPosts.forEach(p => {
                const block = document.createElement('div');
                block.style.marginBottom = '12px';
                block.innerHTML = '<div class="meta">' + new Date(p.timestamp).toLocaleString() + '</div><pre>' + escapeHtml(JSON.stringify(p, null, 2)) + '</pre>';
                postsEl.appendChild(block);
              });
            }
          } catch (err) {
            document.getElementById('files').textContent = '加载失败: ' + err;
            document.getElementById('posts').textContent = '加载失败: ' + err;
          }
        }

        function escapeHtml(str) {
          return String(str).replace(/[&<>]/g, function (s) { return ({'&':'&amp;','<':'&lt;','>':'&gt;'})[s]; });
        }

        // 首次加载并定时刷新
        loadList();
        setInterval(loadList, 5000);
      </script>
    </body>
    </html>
  `);
});

app.listen(PORT, HOST, () => {
  console.log('renwei - 👉 上传接口可用:');
  console.log(`renwei -    - ${uploadEndpoint}`);
});

// 返回已上传文件列表与最近接收的非文件数据
app.get('/api/list', (req, res) => {
  try {
    const filesOnDisk = (fs.readdirSync(uploadsDir) || [])
      .filter(f => f && f[0] !== '.')
      .map(filename => {
        const full = path.join(uploadsDir, filename);
        let stat = null;
        try { stat = fs.statSync(full); } catch (e) { /* ignore */ }
        return {
          filename,
          url: `${PUBLIC_BASE_URL}/uploads/${filename}`,
          size: stat ? stat.size : null,
          mtime: stat ? stat.mtime : null
        };
      });

    res.json({
      status: 'ok',
      files: filesOnDisk,
      recentPosts
    });
  } catch (err) {
    console.error('renwei - /api/list 错误', err);
    res.status(500).json({ status: 'error', message: String(err) });
  }
});